home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- * candisp -
- * Display parts of a canvas onto the screen.
- *
- * Paul Haeberli - 1991
- *
- * exports
- *
- int paintpos(xpos,ypos,pos,strokeno,minm,maxm)
- void displaysetup(drct,scan,sx,sy)
- void displaycanvas(c)
- void setrgbmode(rgb)
- void setcurzoom(z)
- int getcurzoom()
- float getzoomfactor();
- void drawborder(c);
- canvas *screentoscanvas(x1,y1,x2,y2)
- *
- */
- #include "gl.h"
- #include "canvas.h"
- #include "vect.h"
- #include "rct.h"
- #include "math.h"
-
- #define DRAWBUFSIZE (200*200)
-
- static unsigned long *drawbuf;
- static float curzfactor;
- static int curzoom, visible;
- static int visdxorg, visdyorg; /* origin of the vis part in dest coords */
- static int viszxorg, viszyorg; /* origin of the vis part in zoomed coords */
- static rct visrct; /* the visible part of the canvas */
- static rct disprct; /* the displayed rect in screen coords */
- static rct fulldisprct; /* the full rect in screen coords */
- static rct scrrct; /* the screen rect in screen coords */
- static float lastx, lasty;
- static int usergb;
-
- static displaysmallcanvas();
- static mylrectwrite();
-
- int paintpos(xpos,ypos,pos,strokeno,minm,maxm)
- int xpos, ypos;
- vect *pos;
- float minm,maxm;
- {
- float dx, dy, mag, sc;
- int retval;
-
- pos->x = (xpos-visdxorg-scrrct.xmin)/curzfactor;
- pos->y = (ypos-visdyorg-scrrct.ymin)/curzfactor;
- if(strokeno != 0) {
- dx = pos->x-lastx;
- dy = pos->y-lasty;
- mag = fsqrt(dx*dx+dy*dy);
- if(mag>maxm) {
- sc = maxm/mag;
- pos->x = lastx+sc*dx;
- pos->y = lasty+sc*dy;
- lastx = pos->x;
- lasty = pos->y;
- return 1;
- } else if(mag<minm) {
- lastx = pos->x;
- lasty = pos->y;
- return 0;
- }
- }
- lastx = pos->x;
- lasty = pos->y;
- return 1;
- }
-
- void displaysetup(drct,scan,sx,sy)
- rct *drct;
- canvas *scan;
- int sx, sy;
- {
- int centx, centy; /* center of the display */
-
- scrrct = *drct;
- visible = 0;
- rctcenter(drct,¢x,¢y);
- viszxorg = round(centx/curzfactor-sx);
- visdxorg = curzfactor*viszxorg;
- viszyorg = round(centy/curzfactor-sy);
- visdyorg = curzfactor*viszyorg;
- disprct.xmin = 0;
- disprct.xmax = (drct->xmax-drct->xmin)/curzfactor;
- disprct.ymin = 0;
- disprct.ymax = (drct->ymax-drct->ymin)/curzfactor;
- rctoffset(&disprct,-viszxorg,-viszyorg);
- visible = rctinter(&disprct,&scan->area,&visrct);
- fulldisprct = scan->area;
- disprct = visrct;
-
- rctoffset(&disprct,viszxorg,viszyorg);
- disprct.xmax++;
- disprct.ymax++;
- rctscale(&disprct,curzfactor);
- rctoffset(&disprct,drct->xmin,drct->ymin);
- disprct.xmax--;
- disprct.ymax--;
- rctshrink(&disprct,-1,-1);
-
- rctoffset(&fulldisprct,viszxorg,viszyorg);
- fulldisprct.xmax++;
- fulldisprct.ymax++;
- rctscale(&fulldisprct,curzfactor);
- rctoffset(&fulldisprct,drct->xmin,drct->ymin);
- fulldisprct.xmax--;
- fulldisprct.ymax--;
- rctshrink(&fulldisprct,-1,-1);
- }
-
- void displaycanvas(c)
- canvas *c;
- {
- int y, nx, ny, y1, used;
- unsigned long *dptr, *sptr;
-
- if(!visible)
- return;
- if(!rctinter(&visrct,&c->dirt,&c->dirt))
- return;
- if(curzfactor<1.0) {
- displaysmallcanvas(c,visdxorg,visdyorg);
- return;
- }
- if(c->dirt.xmin == 0 && c->dirt.xmax == c->xsize-1) {
- dptr = c->data+c->dirt.ymin*c->xsize;
- mylrectwrite(viszxorg, viszyorg+c->dirt.ymin,
- viszxorg+c->xsize-1,viszyorg+c->dirt.ymax,dptr);
- } else {
- nx = c->dirt.xmax-c->dirt.xmin+1;
- ny = c->dirt.ymax-c->dirt.ymin+1;
- if(!drawbuf)
- drawbuf = (unsigned long *)mymalloc(DRAWBUFSIZE*sizeof(long));
- y1 = c->dirt.ymin;
- while(1) {
- dptr = drawbuf;
- used = 0;
- for(y=y1; y<=c->dirt.ymax; y++) {
- sptr = &c->data[c->dirt.xmin+y*c->xsize];
- bcopy(sptr,dptr,nx*sizeof(long));
- dptr += nx;
- used += nx;
- if((used+nx)>DRAWBUFSIZE)
- break;
- }
- mylrectwrite(viszxorg+c->dirt.xmin,viszyorg+y1,
- viszxorg+c->dirt.xmax,viszyorg+y-1,drawbuf);
- if(y > c->dirt.ymax)
- break;
- y1 = y;
- }
- }
- }
-
- static displaysmallcanvas(c,dx,dy)
- canvas *c;
- int dx, dy;
- {
- int redfactor;
- int x, y, nx, ny, used;
- int x1, x2, y1, y2;
- unsigned long *dptr, *sptr;
-
- redfactor = round(1.0/curzfactor);
- x1 = c->dirt.xmin/redfactor;
- x2 = c->dirt.xmax/redfactor;
- y1 = c->dirt.ymin/redfactor;
- y2 = c->dirt.ymax/redfactor;
- nx = x2 - x1 + 1;
- ny = y2 - y1 + 1;
- if(!drawbuf)
- drawbuf = (unsigned long *)mymalloc(DRAWBUFSIZE*sizeof(long));
- while(1) {
- dptr = drawbuf;
- used = 0;
- for(y=y1; y<=y2; y++) {
- sptr = &c->data[y*redfactor*c->xsize+x1*redfactor];
- x = nx;
- while(x--) {
- *dptr++ = *sptr;
- sptr += redfactor;
- }
- used += nx;
- if((used+nx)>DRAWBUFSIZE)
- break;
- }
- mylrectwrite(dx+x1,dy+y1,dx+x2,dy+y-1,drawbuf);
- if(y > y2)
- break;
- y1 = y;
- }
- }
-
- static mylrectwrite(x1,y1,x2,y2,buf)
- int x1, y1, x2, y2;
- unsigned long *buf;
- {
- int nx, ny;
-
- nx = x2-x1;
- ny = y2-y1;
- if(curzfactor>=1.0) {
- x1 = curzfactor*x1;
- y1 = curzfactor*y1;
- }
- x1 += scrrct.xmin;
- y1 += scrrct.ymin;
- x2 = x1+nx;
- y2 = y1+ny;
- if(usergb)
- lrectwrite(x1,y1,x2,y2,buf);
- else
- ditlrectwrite(x1,y1,x2,y2,buf);
- }
-
- void setrgbmode(rgb)
- int rgb;
- {
- if(rgb) {
- RGBmode();
- gconfig();
- usergb = 1;
- } else {
- cmode();
- gconfig();
- usergb = 0;
- }
- colorinit();
- }
-
- void setcurzoom(z)
- int z;
- {
- curzoom = z;
- if(z>=1)
- curzfactor = z;
- else
- curzfactor = 1.0/(2.0-z);
- if(usergb) {
- if(curzfactor<1.0)
- rectzoom(1.0,1.0);
- else
- rectzoom(curzfactor,curzfactor);
- } else {
- rectzoom(1.0,1.0);
- if(curzfactor<1.0)
- ditrectzoom(1.0,1.0);
- else
- ditrectzoom(curzfactor,curzfactor);
- }
- }
-
- int getcurzoom()
- {
- return curzoom;
- }
-
- float getzoomfactor()
- {
- return curzfactor;
- }
-
- #define DELTA (10.0*curzfactor)
-
- void drawborder(c)
- canvas *c;
- {
- if(!visible) {
- rctfill(&scrrct);
- } else {
- rgbi(64,64,64);
- /* fill bottom */
- if(scrrct.ymin<disprct.ymin)
- fillrect(scrrct.xmin-0.5,scrrct.ymin-0.5,
- scrrct.xmax+1.5,disprct.ymin-0.5);
- /* fill left */
- if(scrrct.xmin<disprct.xmin)
- fillrect(scrrct.xmin-0.5,scrrct.ymin-0.5,
- disprct.xmin-0.5,scrrct.ymax+1.5);
- /* fill right */
- if(scrrct.xmax>disprct.xmax)
- fillrect(disprct.xmax+0.5,scrrct.ymin-0.5,
- scrrct.xmax+0.5,scrrct.ymax+1.5);
- /* fill top */
- if(scrrct.ymax>disprct.ymax)
- fillrect(scrrct.xmin-0.5,disprct.ymax+0.5,
- scrrct.xmax+1.5,scrrct.ymax+1.5);
- /* draw the shadow */
- rgbi(32,32,32);
- fillrect(fulldisprct.xmax+0.5,fulldisprct.ymin-DELTA,
- fulldisprct.xmax+0.5+DELTA,fulldisprct.ymax-DELTA);
- fillrect(fulldisprct.xmin+0.5+DELTA,fulldisprct.ymin-DELTA,
- fulldisprct.xmax+0.5+DELTA,fulldisprct.ymin-0.5);
-
- /* draw the rectangle */
- rgbi(0,0,0);
- rctdraw(&disprct);
- }
- }
-
- canvas *screentocanvas(x1,y1,x2,y2)
- int x1, y1, x2, y2;
- {
- int temp, xsize, ysize;
- canvas *can;
-
- if(x1>x2) {
- temp = x1;
- x1 = x2;
- x2 = temp;
- }
- if(y1>y2) {
- temp = y1;
- y1 = y2;
- y2 = temp;
- }
- xsize = x2-x1+1;
- ysize = y2-y1+1;
- can = newcanvas(xsize,ysize);
- readdisplay(x1,y1,x2,y2,can->data,0);
- return can;
- }
-